﻿// <copyright file="UsersControl.xaml.cs" company="Soumya Chattopadhyay">
// Copyright (c) 2010 All Right Reserved
// </copyright>
// <disclaimer> This software is intented for educational purposes only and not for 
// commerical or prodution use. The software is provided "as is", without warranty 
// of any kind, express or implied, including but not limited to the warranties of 
// merchantability, fitness for a particular purpose and noninfringement. In no event 
// shall the author(s) or copyright holder(s) be liable for any claim, damages or other 
// liability, whether in an action of contract, tort or otherwise, arising from, out of 
// or in connection with the software or the use or other dealings in the software.
// </disclaimer>

namespace My.CodePlex.TFSExplorer
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using Microsoft.TeamFoundation.Server;
    using Microsoft.TeamFoundation.VersionControl.Client;
    using My.CodePlex.TFSExplorer.Resources;
    using My.CodePlex.TFSExplorer.TeamFoundation;

    /// <summary>
    /// Interaction logic for UsersControl.xaml
    /// </summary>
    public partial class UsersControl : UserControl, IExplorerControl
    {
        #region Fields

        /// <summary>
        /// Thread that populates the users tab
        /// </summary>
        private Thread populateUsersThread;

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the UsersControl class
        /// </summary>
        public UsersControl()
        {
            InitializeComponent();

            this.ControlName = Resource.UsersControlName;
            this.Header = Resource.UsersTabItemHeader;
        }

        #endregion

        #region Events

        /// <summary>
        /// Notify listeners that the display user has changed
        /// </summary>
        public event Action<string> OnDisplayUserChanged;

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets  the control name
        /// </summary>
        public string ControlName { get; set; }

        /// <summary>
        /// Gets or sets the control tab item header
        /// </summary>
        public string Header { get; set; }

        #endregion

        #region Public methods

        /// <summary>
        /// Public method called to start the thread to populate the source tree
        /// </summary>
        /// <param name="tfsContext">The TFS context</param>
        public void Populate(TeamFoundationContext tfsContext)
        {
            // Set up the thread to populate the source tree view
            this.populateUsersThread = new Thread(this.PopulateUsers);
            this.populateUsersThread.SetApartmentState(ApartmentState.STA);
            this.populateUsersThread.Start(TeamFoundationContext.CurrentProject.ServerItem);
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Populates the source tree from the version control server
        /// </summary>
        /// <param name="data">Name of the topmost folder in source tree</param>
        private void PopulateUsers(object data)
        {
            Identity[] appGroups = new Identity[] { };

            try
            {
                appGroups = TeamFoundationContext.GroupSecurityService.ListApplicationGroups(TeamFoundationContext.VersionControlServer.GetTeamProject(TeamFoundationContext.CurrentProject.Name).ArtifactUri.AbsoluteUri);
            }
            catch (VersionControlException)
            {
                // TODO: 
            }

            SourceItem virRoot = new SourceItem();
            ObservableCollection<SourceItem> obsCollection = new ObservableCollection<SourceItem>();

            foreach (Identity group in appGroups)
            {
                Identity[] groupMembers = TeamFoundationContext.GroupSecurityService.ReadIdentities(SearchFactor.Sid, new string[] { group.Sid }, QueryMembership.Expanded);
                foreach (Identity member in groupMembers)
                {
                    SourceItem treeViewItem = new SourceItem();
                    treeViewItem.Tag = member;
                    treeViewItem.Name = member.DisplayName;
                    this.CreateTooltip(treeViewItem, member);

                    if (member.Members != null)
                    {
                        foreach (string memberSid in member.Members)
                        {
                            Identity memberInfo = TeamFoundationContext.GroupSecurityService.ReadIdentity(SearchFactor.Sid, memberSid, QueryMembership.None);

                            SourceItem treeViewItemMember = new SourceItem();
                            treeViewItemMember.Name = memberInfo.DisplayName;
                            treeViewItemMember.Tag = memberInfo;
                            this.CreateTooltip(treeViewItemMember, memberInfo);

                            treeViewItem.Items.Add(treeViewItemMember);
                        }
                    }

                    virRoot.Items.Add(treeViewItem);
                }
            }

            this.UsersView.Dispatcher.BeginInvoke((Action)(() =>
            {
                this.UsersView.ItemsSource = virRoot.Items;
            }));
        }

        /// <summary>
        /// Create tooltips for users with details
        /// </summary>
        /// <param name="treeViewItem">The tree view item representing the user</param>
        /// <param name="member">The user details</param>
        private void CreateTooltip(SourceItem treeViewItem, Identity member)
        {
            StringBuilder memberTooltip = new StringBuilder();
            memberTooltip.Append(member.Domain + "\\" + member.AccountName + Environment.NewLine);

            if (!string.IsNullOrEmpty(member.MailAddress))
            {
                memberTooltip.Append(member.MailAddress + Environment.NewLine);
                //// TODO: Color this blue
            }

            memberTooltip.Append("IsSecurityGroup: " + member.SecurityGroup.ToString() + Environment.NewLine);
            memberTooltip.Append("Type: " + member.Type.ToString() + Environment.NewLine);
            memberTooltip.Append("SpecialType: " + member.SpecialType.ToString());

            treeViewItem.Description = memberTooltip.ToString();
        }

        /// <summary>
        /// Set the current display user to the selected value
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void UsersViewSetDisplayUserClick(object sender, RoutedEventArgs e)
        {
            MenuItem menuItem = sender as MenuItem;

            if (this.UsersView.SelectedItem != null)
            {
                SourceItem treeViewItem = this.UsersView.SelectedItem as SourceItem;
                Identity userId = treeViewItem.Tag as Identity;
                string userName = userId.Domain + "\\" + userId.AccountName;

                if (string.Compare(TeamFoundationContext.CurrentDisplayUser, userName, true, CultureInfo.CurrentUICulture) != 0)
                {
                    TeamFoundationContext.CurrentDisplayUser = userName;

                    if (this.OnDisplayUserChanged != null)
                    {
                        this.OnDisplayUserChanged(userName);
                    }
                }
            }
        }

        #endregion
    }
}
